﻿#define DEBUG

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Windows.Forms;
using log4net;
using System.Collections.Specialized;

namespace KokosSearcher
{
	public class KokosData
	{
		private static readonly ILog log = LogManager.GetLogger(typeof(Program));

		private string _key = "a5e6c2a2d245b1e02a95b1e835fd37f2";
		private KokosAuction _auction;
		private AuctionUser _user;

		public KokosAuction Auction
		{
			get { return this._auction; }
			set { this._auction = value; }
		}

		public AuctionUser User
		{
			get { return this._user; }
			set { this._user = value; }
		}

		/// <summary>
		/// Zwraca dane aukjci o wskazanym identyfikatorze.
		/// </summary>
		/// <param name="p_AuctionId">Identyfiator aukcji</param>
		/// <returns></returns>
		public bool getAuctionData(string p_AuctionId)
		{
			string responseFromServer = "";

#if DEBUG
			responseFromServer = File.ReadAllText(@"...\...\KokosSearcherTests\auctionDataTest.xml");
#else
			string requestUrl = "https://kokos.pl/webapi/get-auction-data?key=" + this._key + "&id=" + p_AuctionId;

			responseFromServer = this.responseFromServer(requestUrl);
#endif
			if (!responseFromServer.Contains("Nie ma takiej aukcji"))
			{
				this._auction = new KokosAuction(responseFromServer);
				this._user = this._auction.User;
			}
			
			return true;
		} // getAuctionData

		public List<KokosAuction> search(SearchParameters p_oSearchParameters)
		{
			return this.search(p_oSearchParameters.User, p_oSearchParameters.Title, p_oSearchParameters.OkresOd, p_oSearchParameters.OkresDo, p_oSearchParameters.ProcentOd, p_oSearchParameters.ProcentDo, p_oSearchParameters.ZakonczonaOd, p_oSearchParameters.ZakonczonaDo, p_oSearchParameters.Page);
		}

		/// <summary>
		/// Funkcja służy do wyszukiwania aukcji po zadanych parametrach
		/// </summary>
		/// <param name="p_user">Może to być nazwa lub fragment nazwy użytkownika</param>
		/// <param name="p_title">Może to być tytuł aukcji lub jego fragment</param>
		/// <param name="p_periodFrom">Będą pokazane aukcje, których okres spłat będzie większy lub równy od tego parametru</param>
		/// <param name="p_periodTo">Będą pokazane aukcje, których okres spłat będzie mniejszy lub równy od tego parametru</param>
		/// <param name="p_percentFrom">Będą pokazane aukcje, których oprocentowanie będzie większe lub równe od tego parametru</param>
		/// <param name="p_percentTo">Będą pokazane aukcje, których oprocentowanie będzie mniejsze lub równe od tego parametru</param>
		/// <param name="p_completedFrom">Będą pokazane aukcje, których są zrealizowane w co najmniej tylu procentach</param>
		/// <param name="p_completedTo">Będą pokazane aukcje, których są zrealizowane maksymalnie tylu procentach</param>
		/// <param name="p_strona">Numer strony z wynikami</param>
		/// <returns>Lista obiektów reprezentującyh znalezione aukcje</returns>
		public List<KokosAuction> search(string p_user, string p_title, string p_periodFrom, string p_periodTo, string p_percentFrom, string p_percentTo, string p_completedFrom, string p_completedTo, string p_strona)
		{
			string zapytanie = @"https://kokos.pl/webapi/search?key=" + this._key;

			List<KokosAuction> listaZnalezionychAukcji = new List<KokosAuction>();

			// w zależności od parametrów składamy odpowiednie zapytanie do WebAPI
			if (!String.IsNullOrEmpty(p_user))
			{
				zapytanie += "&user=" + p_user;
			}

			if (!String.IsNullOrEmpty(p_title))
			{
				zapytanie += "&title=" + p_title;
			}

			if (!String.IsNullOrEmpty(p_periodFrom))
			{
				zapytanie += "&periodFrom=" + p_periodFrom;
			}

			if (!String.IsNullOrEmpty(p_periodTo))
			{
				zapytanie += "&periodTo=" + p_periodTo;
			}

			if (!String.IsNullOrEmpty(p_percentFrom))
			{
				zapytanie += "&percentFrom=" + p_percentFrom;
			}

			if (!String.IsNullOrEmpty(p_percentTo))
			{
				zapytanie += "&percentTo=" + p_percentTo;
			}

			if (!String.IsNullOrEmpty(p_completedFrom))
			{
				zapytanie += "&completedFrom=" + p_completedFrom;
			}

			if (!String.IsNullOrEmpty(p_completedTo))
			{
				zapytanie += "&completedTo=" + p_completedTo;
			}

			if (!String.IsNullOrEmpty(p_strona))
			{
				zapytanie += "&page=" + p_strona;
			}

			// add only the usefull ratings
			zapytanie += this.getAllRatings(false);

			if (!String.IsNullOrEmpty(zapytanie))
			{
				string xmlResponse = "";
//#if DEBUG
//                xmlResponse = File.ReadAllText(@"...\...\...\KokosSearcherTests\searchAuctions.xml");
//#else
				log.Debug("Sending request: " + zapytanie);

				xmlResponse = this.responseFromServer(zapytanie);
//#endif
				if (!String.IsNullOrEmpty(xmlResponse))
				{
					XmlDocument xmlDoc = new XmlDocument();
					xmlDoc.LoadXml(xmlResponse);
					KokosAuction auction = null;

					log.Debug("Auctions count: " + xmlDoc.SelectSingleNode("//response/paging/total").InnerText);

					foreach (XmlElement xmlElement in xmlDoc.SelectNodes("//response/auctions/auction"))
					{
						auction = new KokosAuction(xmlElement);
						
						if (auction.Id > 0)
						{
							listaZnalezionychAukcji.Add(auction);
						}
					}
					//foreach (XmlNode xmlNode in xmlDoc.SelectNodes("//response/auctions/auction"))
					//{
					//    listaZnalezionychAukcji.Add(new KokosAuction(xmlNode));
					//}
				}
			}

			return listaZnalezionychAukcji;
		}

		private string getAllRatings(bool p_showRedStars)
		{
			StringCollection _ratingList = new StringCollection();

			string _rating = "&rating=";

			_ratingList.Add("100"); //100 	Jedna zielona gwiazdka
			_ratingList.Add("200"); //200 	Dwie zielone gwiazdki
			_ratingList.Add("300"); //300 	Trzy zielone gwiazdki
			_ratingList.Add("400"); //400 	Cztery zielone gwiazdki
			_ratingList.Add("500"); //500 	Pięć zielonych gwiazdek

			_ratingList.Add("1100"); //1100 	Jedna niebieska gwiazdka
			_ratingList.Add("1200"); //1200 	Dwie niebieskie gwiazdki
			_ratingList.Add("1300"); //1300 	Trzy niebieskie gwiazdki
			_ratingList.Add("1400"); //1400 	Cztery niebieskie gwiazdki
			_ratingList.Add("1500"); //1500 	Pięć niebieskich gwiazdek

			if (p_showRedStars)
			{
				_ratingList.Add("110"); //110 	Czerwona gwiazdka
				_ratingList.Add("210"); //210 	Dwie gwiazdki, w tym jedna czerwona.
				_ratingList.Add("310"); //310 	Trzy gwiazdki, w tym jedna czerwona.
				_ratingList.Add("410"); //410 	Cztery gwiazdki, w tym jedna czerwona.
				_ratingList.Add("510"); //510 	Pięć gwiazdek, w tym jedna czerwona.
			}

			foreach (string rating in _ratingList)
			{
				_rating += rating + ",";
			}

			return _rating.Substring(0,_rating.Length - 1);
		}

		public List<KokosAuction> searchWithFilters(FilterGroup p_FilterGroupBox)
		{
			string lcOkresDo, lcOkresOd, lcUser, lcTitle, lcProcentOd, lcProcentDo, lcZakonczonaOd, lcZakonczonaDo, lcStrona;

			lcOkresDo       = "";
			lcOkresOd       = "";
			lcUser		    = "";
			lcTitle		    = "";
			lcProcentOd	    = "";
			lcProcentDo	    = "";
			lcZakonczonaOd	= "";
			lcZakonczonaDo	= "";
			lcStrona        = "";

			foreach (Control filterBox in p_FilterGroupBox.Controls)
			{
				if (filterBox.GetType() == typeof(TextBox))
				{
					switch (filterBox.Tag.ToString().ToLower())
					{
						case "okresod":
							lcOkresOd = filterBox.Text;
							break;
						case "okresdo":
							lcOkresDo = filterBox.Text;
							break;
						case "strona":
							lcStrona = filterBox.Text;
							break;
						default:
							break;
					}	
				}
			}

			return this.search(lcUser, lcTitle, lcOkresOd, lcOkresDo, lcProcentOd, lcProcentDo, lcZakonczonaOd, lcZakonczonaDo, lcStrona);
		}

		/// <summary>
		/// Funkcja odpytuje WebApi zgodnie z pytaniem przekazanym jako parametr
		/// </summary>
		/// <param name="p_requestUrl">Pełny url z zapytaniem do serwera</param>
		/// <returns>Zwraca odpowiedź serwera w postaci XML'a</returns>
		private string responseFromServer(string p_requestUrl)
		{
			string responseFromServer = "";

			log.Debug("Sending request to WebAPI");

			WebRequest request = WebRequest.Create(p_requestUrl);
			WebResponse response = request.GetResponse();
#if DEBUG
			Console.WriteLine(((HttpWebResponse)response).StatusDescription);
#endif
			Stream dataStream = response.GetResponseStream();

			log.Debug("Reading the stream.");

			// Open the stream using a StreamReader for easy access.
			StreamReader reader = new StreamReader(dataStream);
			// Read the content.
			responseFromServer = reader.ReadToEnd();			

			response.Close();
			reader.Close();

			log.Debug("Stream was read");

			return responseFromServer;
		}

		internal string saveAuctionToDB(KokosAuction p_Auction)
		{
			string ret = "";

			if (new AuctionsDB().addAuction(p_Auction))
			{
				ret = "Dodano aukcję do bazy";
			}

			return ret;
		}

	} // KokosData

	public class SearchParameters
	{
		public string PeriodFrom, PeriodTo, User, Title, PercentFrom, PercentTo, RealizationFrom, RealizationTo, ValueFrom, ValueTo, Page, InvestorsAmountFrom, InvestorsAmountTo;

	} // SearchParameters
}
